package com.zhdl.modules.demo.DCHTProcess;

//import com.zhdl.modules.common.entity.ConfigurationPLc;
//import com.zhdl.modules.common.test.GetPLCValue;

import cn.hutool.core.util.HexUtil;
import com.project.common.util.DelayUtil;
import com.zhdl.common.ytools.BaseConversionTools;
import com.zhdl.common.ytools.BitConversionTools;
import com.zhdl.common.ytools.callback.CommonCallback;
import com.zhdl.hardware_contact.hardware_common.param.CurrencyProtocolReadReq;
import com.zhdl.hardware_contact.hardware_common.param.CurrencyProtocolWriteReq;
import com.zhdl.hardware_contact.hardware_common.param.TcpAssembleCmdPkg;
import com.zhdl.hardware_contact.hardware_config.entity.ProjectConfiguration;
import com.zhdl.modules.process.common.GetPLCValue;
import com.zhdl.network.other_protocol.modbustcp.ModbusTcpRespPkg;
import com.zhdl.network.strategy.common_client.impl.CommonProtocolStrategy;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.util.TextUtils;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Component
@Data
@Slf4j
public class CHTRobotInterface implements GetPLCValue {
    @Resource
    ThreadPoolTaskScheduler threadPoolTaskScheduler;
    @Resource
    CommonProtocolStrategy commonProtocolStrategy;
    public final String PICK_DONE = "pick_done";
    public final String PICK_DONE_OK = "pick_done_ok";
    public final String ROBOT_RUNNING = "robot_running";
    public final String MOVE_CAMERA_1_1 = "move_camera_1_1";
    public final String MOVE_CAMERA_1_2 = "move_camera_1_2";
    public final String MOVE_PICK = "move_pick";
    public final static String MOVE_PUT_1 = "move_put_1";
    public final static String MOVE_PUT_2 = "move_put_2";
    public final static String MOVE_PUT_3 = "move_put_3";
    public final static String MOVE_PUT_4 = "move_put_4";
    public final static String MOVE_PUT_5 = "move_put_5";
    public final static String MOVE_PUT_6 = "move_put_6";
    public final static String MOVE_HOME = "move_home";
    public final static String MOVE_WORK = "move_work_1";
    public final static String MOVE_WORK_2 = "move_work_2";
    public final static String COORDINATE_OK = "coordinate0_ok";
    public final static String COORDINATE_END = "coordinate0_end";
    public final static String PICK_LOCATION_DONE = "pick_location_done";
    public final static String PUT_LOCATION_DONE = "put_location_done";
    List<ProjectConfiguration> configurationPLcList;
    public final static String ROBOT_IP = "192.168.60.68:502";
    // public final String ROBOT_IP = "192.168.60.101:502";
    private String lastFlag = "";

    public void initData() {
        configurationPLcList = new ArrayList<>();
        configurationPLcList.add(new ProjectConfiguration(ROBOT_RUNNING, "0", 1));
        configurationPLcList.add(new ProjectConfiguration(MOVE_CAMERA_1_1, "0", 1));
        configurationPLcList.add(new ProjectConfiguration(MOVE_CAMERA_1_2, "0", 1));
        configurationPLcList.add(new ProjectConfiguration(MOVE_PICK, "0", 1));
        configurationPLcList.add(new ProjectConfiguration(MOVE_PUT_1, "0", 1));
        configurationPLcList.add(new ProjectConfiguration(MOVE_PUT_2, "0", 1));
        configurationPLcList.add(new ProjectConfiguration(MOVE_PUT_3, "0", 1));
        configurationPLcList.add(new ProjectConfiguration(MOVE_PUT_4, "0", 1));
        configurationPLcList.add(new ProjectConfiguration(MOVE_PUT_5, "0", 1));
        configurationPLcList.add(new ProjectConfiguration(MOVE_PUT_6, "0", 1));
        configurationPLcList.add(new ProjectConfiguration(MOVE_HOME, "0", 1));
        configurationPLcList.add(new ProjectConfiguration(MOVE_WORK, "0", 1));
        configurationPLcList.add(new ProjectConfiguration(MOVE_WORK_2, "0", 1));
        configurationPLcList.add(new ProjectConfiguration(COORDINATE_OK, "0", 1));
        configurationPLcList.add(new ProjectConfiguration(COORDINATE_END, "0", 1));
        configurationPLcList.add(new ProjectConfiguration(PICK_LOCATION_DONE, "0", 1));
        configurationPLcList.add(new ProjectConfiguration(PUT_LOCATION_DONE, "0", 1));

        threadPoolTaskScheduler.scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {
                CurrencyProtocolReadReq currencyProtocolReadReq = new CurrencyProtocolReadReq();
                currencyProtocolReadReq.setId("01");
                currencyProtocolReadReq.setReadNumber("0030");
                currencyProtocolReadReq.setStartAddress("000E");
                try {
                    commonProtocolStrategy.sendCmd(ROBOT_IP, HexUtil.encodeHexStr(TcpAssembleCmdPkg.read03(currencyProtocolReadReq)), s -> {
                        // log.info("读到机器人数据" + ModbusTcpRespPkg.getDataFor03(s));
                        s = ModbusTcpRespPkg.getDataFor03(s);
                        String substring = s.substring(0, 4);
                        String s1 = BitConversionTools.HexStrConversionBit(substring);
                        // log.info("16位数据" + s1);
                        getValue(ROBOT_RUNNING).setValue(s1.contains("1") ? "1" : "0");
                        if (s1.contains("1") && !lastFlag.contains("1")) {
                            CurrencyProtocolWriteReq currencyProtocolReadReq1 = new CurrencyProtocolWriteReq();
                            currencyProtocolReadReq1.setId("01");
                            currencyProtocolReadReq1.setStartAddress("0110");
                            currencyProtocolReadReq1.setWriteValue("00000000");

                            CurrencyProtocolWriteReq currencyProtocolReadReq2 = new CurrencyProtocolWriteReq();
                            currencyProtocolReadReq2.setId("01");
                            currencyProtocolReadReq2.setStartAddress("0107");
                            currencyProtocolReadReq2.setWriteValue("0000");


                            try {
                                commonProtocolStrategy.sendCmd(ROBOT_IP, HexUtil.encodeHexStr(TcpAssembleCmdPkg.write10(new CurrencyProtocolWriteReq("01", "010F", "00000000"))));
                            } catch (IOException e) {
                                throw new RuntimeException(e);
                            }

                            try {
                                commonProtocolStrategy.sendCmd(ROBOT_IP, HexUtil.encodeHexStr(TcpAssembleCmdPkg.write10(currencyProtocolReadReq1)), new CommonCallback<String>() {
                                    @Override
                                    public void statusCallback(String s) {
                                        log.info(s);
                                    }
                                });

                                commonProtocolStrategy.sendCmd(ROBOT_IP, HexUtil.encodeHexStr(TcpAssembleCmdPkg.write10(currencyProtocolReadReq2)), new CommonCallback<String>() {
                                    @Override
                                    public void statusCallback(String s) {
                                        log.info(s);
                                    }
                                });


                            } catch (IOException e) {
                                throw new RuntimeException(e);
                            }
                        }
                        lastFlag = s1;
                        String ai = s.substring(52, 60);
                        // log.info("ai原始数据" + ai);
                        float v = BaseConversionTools.hexToFloat(ai.substring(4, 8) + ai.substring(0, 4));
                        setFlagByV(v);
                        //  log.info("机器人交互AI" + v);
                    });
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }, 500);
    }

    private void setFlagByV(float v) {
        int flag = (int) v;
        if (flag == 0) {
            return;
        }
        switch (flag) {
            case 2 -> getValue(MOVE_CAMERA_1_1).setValue("1");
            case 3 -> getValue(MOVE_CAMERA_1_2).setValue("1");
            case 4 -> getValue(MOVE_PICK).setValue("1");
            case 5 -> getValue(MOVE_PUT_1).setValue("1");
            case 6 -> getValue(MOVE_PUT_2).setValue("1");
            case 7 -> getValue(MOVE_PUT_3).setValue("1");
            case 8 -> getValue(MOVE_PUT_4).setValue("1");
            case 9 -> getValue(MOVE_PUT_5).setValue("1");
            case 10 -> getValue(MOVE_PUT_6).setValue("1");
            case 11 -> getValue(MOVE_HOME).setValue("1");
            case 12 -> getValue(MOVE_WORK).setValue("1");
            case 14 -> getValue(MOVE_WORK_2).setValue("1");
            case 17 -> getValue(COORDINATE_OK).setValue("1");
            case 18 -> getValue(COORDINATE_END).setValue("1");
            case 99 ->  getValue(PICK_LOCATION_DONE).setValue("1");
            case 100 ->getValue(PUT_LOCATION_DONE).setValue("1");
        }
    }

    float currentNum = 2.0f;
    int currentStep = 0;

    public void moveByStep(float step) {
        if (getValue(ROBOT_RUNNING).value.equals("1")) {
            log.info("当前机器人正在运动中.....");
            return ;
        }
        currentStep = (int) step;
        reSetAll();
        CurrencyProtocolWriteReq currencyProtocolReadReq1 = new CurrencyProtocolWriteReq();
        currencyProtocolReadReq1.setId("01");
        currencyProtocolReadReq1.setStartAddress("0108");
        currencyProtocolReadReq1.setWriteValue("FFFF");

        CurrencyProtocolWriteReq currencyProtocolReadReq = new CurrencyProtocolWriteReq();
        currencyProtocolReadReq.setId("01");
        currencyProtocolReadReq.setStartAddress("010F");

        String s1 = BaseConversionTools.floatTo8hexHL(step);
        if (step == 4.0f){
            s1 = BaseConversionTools.floatTo8hexHL(99.0f);
        }
        String s2 = BaseConversionTools.floatTo8hexHL(currentNum);
        if (step == 2.0f) {
            currencyProtocolReadReq.setWriteValue(s1 + s2);
        } else {
            currencyProtocolReadReq.setWriteValue(s1);
        }
        try {
            log.info(HexUtil.encodeHexStr(TcpAssembleCmdPkg.write10(currencyProtocolReadReq)));

            commonProtocolStrategy.sendCmd(ROBOT_IP, HexUtil.encodeHexStr(TcpAssembleCmdPkg.write10(currencyProtocolReadReq)), s -> {

            }, 2000);

            DelayUtil.delayedExecution(500, new Runnable() {
                @Override
                public void run() {
                    try {
                        commonProtocolStrategy.sendCmd(ROBOT_IP, HexUtil.encodeHexStr(TcpAssembleCmdPkg.write10(currencyProtocolReadReq1)), new CommonCallback<String>() {
                            @Override
                            public void statusCallback(String s) {
                                log.info(s);
                            }
                        });
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            });

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    public void setCameraResult(boolean ok,String result){

        if (ok){
            if (!TextUtils.isEmpty(result)){
                String[] split = result.split(",");
                if (split.length == 3){
                    String location = BaseConversionTools.floatTo8hexHL(Float.parseFloat(split[0])) + BaseConversionTools.floatTo8hexHL(Float.parseFloat(split[1])) + BaseConversionTools.floatTo8hexHL(Float.parseFloat(split[2]));
                    CurrencyProtocolWriteReq currencyProtocolReadReq = new CurrencyProtocolWriteReq();
                    currencyProtocolReadReq.setId("01");
                    currencyProtocolReadReq.setStartAddress("0113");
                    currencyProtocolReadReq.setWriteValue(location);
                    try {
                        commonProtocolStrategy.sendCmd(ROBOT_IP, HexUtil.encodeHexStr(TcpAssembleCmdPkg.write10(currencyProtocolReadReq)));
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
            try {
                commonProtocolStrategy.sendCmd(ROBOT_IP, HexUtil.encodeHexStr(TcpAssembleCmdPkg.write10(new CurrencyProtocolWriteReq("01", "0109", "0000"))));
            } catch (IOException e) {
                log.info(e.getMessage());
            }

        }else{
            try {
                commonProtocolStrategy.sendCmd(ROBOT_IP, HexUtil.encodeHexStr(TcpAssembleCmdPkg.write10(new CurrencyProtocolWriteReq("01", "0109", "FFFF"))));
            } catch (IOException e) {
                log.info(e.getMessage());
            }
        }

        try {
            commonProtocolStrategy.sendCmd(ROBOT_IP, HexUtil.encodeHexStr(TcpAssembleCmdPkg.write10(new CurrencyProtocolWriteReq("01", "0107", "FFFF"))));
        } catch (IOException e) {
            log.info(e.getMessage());
        }
        DelayUtil.delayedExecution(1000, new Runnable() {
            @Override
            public void run() {
                try {
                    commonProtocolStrategy.sendCmd(ROBOT_IP, HexUtil.encodeHexStr(TcpAssembleCmdPkg.write10(new CurrencyProtocolWriteReq("01", "0107", "0000"))));
                } catch (IOException e) {
                    log.info(e.getMessage());
                }
            }
        });


    }
    public String getVStrByStep(float step) {
        String vStr = "";
        int i = (int) step;
        switch (i) {
            case 2 -> vStr = MOVE_CAMERA_1_1;
            case 3 -> vStr = MOVE_CAMERA_1_2;
            case 4 -> vStr = MOVE_PICK;
            case 5 -> vStr = MOVE_PUT_1;
            case 6 -> vStr = MOVE_PUT_2;
            case 7 -> vStr = MOVE_PUT_3;
            case 8 -> vStr = MOVE_PUT_4;
            case 9 -> vStr = MOVE_PUT_5;
            case 10 -> vStr = MOVE_PUT_6;
            case 11, 15, 13 ,100 -> vStr = MOVE_HOME;
            case 12 -> vStr = MOVE_WORK;
            case 14 -> vStr = MOVE_WORK_2;
            case 17 -> vStr = COORDINATE_OK;
            case 18 -> vStr = COORDINATE_END;
            case 99 -> vStr = PICK_LOCATION_DONE;
            case 16 -> vStr = PUT_LOCATION_DONE;
        }
        return vStr;
    }


    public String getDescByStep(float step) {
        return switch ((int) step) {
            case 2 -> "机器人移动至拍照位置1";
            case 3 -> "机器人移动至拍照位置2";
            case 4 -> "机器人根据视觉结果引导抓取,回到等待位";
            case 5 -> "移动至套树脂环位置1";
            case 6 -> "移动至套环位置2";
            case 7 -> "移动至第三个位置";
            case 8 -> "移动至第四个位置";
            case 9 -> "移动至第五个位置";
            case 10 -> "移动至第六个位置";
            case 11 -> "机器人回HOME";
            case 12, 14 -> "机器人去打螺丝位置";
            case 13, 15 -> "机器人回等待位";
            case 16 -> "机器人放回成品";
            case 17 -> "标定程序启动";
            case 18 -> "标定结束";
            case 99 -> "机器人夹具夹紧";
            case 100 -> "机器人夹具松开";
            default -> "";
        };
    }

    public void reSetAll() {
        for (ProjectConfiguration projectConfiguration : configurationPLcList) {
            if (projectConfiguration.valueType == 1) {
                projectConfiguration.value = "0";
            }
        }
    }

    @Override
    public ProjectConfiguration getValue(String field) {
        for (ProjectConfiguration configurationPLc : configurationPLcList) {
            if (configurationPLc.getField().equals(field)) {
                return configurationPLc;
            }
        }
        return null;
    }


}
